package com.xneure.utils;

import java.math.BigDecimal;
import java.util.Arrays;
import com.xneure.utils.exception.ParseException;

public class NumUtil{
	private static char[] UPPERCHAR = {'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'};
	private static char[] GROUPUNIT = {'元','万','亿','兆'};
	private static char[] INTUNIT = {'拾','佰','千'};
	private static char[] DECIUNIT = {'角','分','厘','毫'};
	private static int GROUPLENGTH = 4;

	/**
	 * 金额转换为大写
	 */
	public static String convert(BigDecimal money){
		String[] m;
		String string = money.toString();
		int ind = string.indexOf(".");
		if(ind > -1){
			char[] charArray = string.toCharArray();
			m = new String[]{new String(Arrays.copyOfRange(charArray,0,ind)),new String(Arrays.copyOfRange(charArray,ind + 1,charArray.length))};
		}else{
			m = new String[]{string};
		}
		if(m[0].startsWith("-")){
			m[0] = m[0].replace("-","");
		}
		int intLength = m[0].length();
		if(intLength > GROUPUNIT.length * GROUPLENGTH){
			throw new ParseException("整数部分超出处理范围，最多支持" + GROUPUNIT.length * GROUPLENGTH + "位小数。");
		}
		int decLength = 0;
		if(m.length > 0){
			decLength = m[1].length();
			if(decLength > 4){
				throw new ParseException("小数部分超出处理范围，最多支持4位小数。");
			}
		}
		int gCount = StrUtil.stringRowCount(m[0],GROUPLENGTH / 2);
		char[] src = toUpperChar(m[0].toCharArray());
		char[][] tem = group(src,gCount);
		StringBuilder sb = new StringBuilder(intLength + gCount + decLength);
		if(money.doubleValue() < 0){
			sb.append("负");
		}
		char[] mu = new char[4];
		System.arraycopy(INTUNIT,0,mu,1,3);
		for(int i = tem.length;i > 0;i--){
			mu[0] = GROUPUNIT[i - 1];
			sb.append((intUnit(tem[i - 1],mu)));
		}
		if(m.length > 1){
			char[] cs = toUpperChar(m[1].toCharArray());
			sb.append((decUnit(cs,DECIUNIT)));
		}else{
			sb.append("整");
		}
		return sb.toString();
	}

	/**
	 * 添加金额单位
	 */
	private static char[] decUnit(char[] numb,char[] unit){
		int nl = numb.length;
		char[] c = new char[nl * 2];
		for(int i = 0;i < nl;i++){
			int pp = i * 2;
			char n = numb[i];
			if(n != '零'){
				c[pp] = n;
				c[pp + 1] = unit[i];
			}else if(i == 0){
				c[pp] = n;
			}
		}
		return StrUtil.delNullChar(c);
	}

	/**
	 * 添加金额单位
	 */
	private static char[] intUnit(char[] numb,char[] unit){
		int nl = numb.length;
		int ul = 0;
		char[] c = new char[nl * 2];
		for(int i = nl;i > 0;i--){
			int pp = c.length - ((nl - i) * 2) - 1;
			char n = numb[i - 1];
			if(n != '零'){
				c[pp - 1] = n;
				c[pp] = unit[ul];
			}else if(i == nl){
				c[pp] = unit[ul];
			}else if(c[pp + 1] != '零' && c[pp + 1] != 0){
				c[pp] = n;
			}
			++ul;
		}
		return StrUtil.delNullChar(c);
	}

	/**
	 * 数字转大写
	 */
	private static char[] toUpperChar(char[] chars){
		for(int i = 0;i < chars.length;i++){
			chars[i] = UPPERCHAR[chars[i] - '0'];
		}
		return chars;
	}

	/**
	 * 对数据进行分组
	 */
	private static char[][] group(char[] chars,int glen){
		int length = chars.length;
		int s = length - GROUPLENGTH, e = length;
		char[][] tem = new char[glen][];
		for(int i = 0;i < glen;i++){
			tem[i] = Arrays.copyOfRange(chars,s,e);
			if(s - GROUPLENGTH < 0){
				e = s;
				s = 0;
			}else{
				s -= GROUPLENGTH;
				e -= GROUPLENGTH;
			}
		}
		return tem;
	}

	/**
	 * 是否为偶数(双数)
	 * 
	 * @param num
	 * @return boolean
	 */
	public static boolean isEven(int num){
		return (num & 1) == 0;
	}

	public static boolean isNum(Object o){
		if(o instanceof Number){
			return true;
		}else if(o instanceof String){
			try{
				Double.parseDouble(o.toString());
				return true;
			}catch(Exception e){
				try{
					Long.parseLong(o.toString());
					return true;
				}catch(Exception es){
					return false;
				}
			}
		}else{
			return false;
		}
	}

	/**
	 * 保留指定位数的小数
	 * 
	 * @param d
	 * @param digit
	 * @return double
	 */
	public static double decimals(Double d,int digit){
		BigDecimal b = new BigDecimal(d.toString());
		return b.setScale(digit,BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 转换为浮点数
	 * 
	 * @param obj
	 */
	public static double convertDouble(Object obj){
		try{
			if(null == obj || obj.toString().trim().length() < 1){
				return 0.0;
			}else{
				if(obj instanceof Double){
					return (Double)obj;
				}else{
					return Double.parseDouble(obj.toString());
				}
			}
		}catch(Exception e){
			return 0.0;
		}
	}

	/**
	 * 获取字符串中的数值，取值长度第一个不为数值的之后处。
	 * 
	 * @param s
	 * @return int
	 */
	public static long getLong(String s){
		StringBuilder sBuilder = new StringBuilder(s.length());
		for(char c:s.toCharArray()){
			if(c >= '0' && c <= '9'){
				sBuilder.append(c);
			}else{
				break;
			}
		}
		if(sBuilder.length() < 1){
			return 0;
		}
		return Long.valueOf(sBuilder.toString());
	}

	public static boolean checkRange(long num,long mix,long max){
		return num > mix && num < max;
	}

	public static boolean checkRange(double num,double mix,double max){
		return num > mix && num < max;
	}
}
